package com.github.hgbit.config;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;

import com.github.hgbit.properties.SwaggerProperties;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * SwaggerConfig.
 *
 * @author huangguan
 */
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "web.swagger", value = "enabled", havingValue = "true")
public class SwaggerAutoConfig {

    /**
     * Docket.
     *
     * @return docket
     */
    @Bean
    @ConditionalOnMissingBean
    public Docket createRestApi(SwaggerProperties swaggerProperties) {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo(swaggerProperties))
                .select()
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
                .paths(excludePaths(swaggerProperties))
                .build();
    }

    /**
     * exclude paths.
     */
    private Predicate<String> excludePaths(SwaggerProperties swaggerProperties) {
        String excludePaths = swaggerProperties.getExcludePaths();
        List<Predicate<String>> exclude = new ArrayList<>();
        if (!StringUtils.isEmpty(excludePaths)) {
            exclude = Arrays.stream(excludePaths.split(","))
                .map(PathSelectors::ant)
                .collect(Collectors.toList());
        }
        return Predicates.not(Predicates.or(exclude));
    }

    /**
     * 用来创建该Api的基本信息.
     *
     */
    private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
        return new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .version(swaggerProperties.getVersion())
                .build();
    }

}